#region Usings

using System.IO;
using System.Web;
using log4net;
using Karma.Framework.Core.Services.Invoker.Processor;

#endregion

namespace Karma.Framework.Core.Services.Invoker.Adapter
{
    public class HttpAdapter : IAdapter
    {
        private static ILog LOG = LogManager.GetLogger(typeof (HttpAdapter).Name);

        public HttpAdapter(IProcessor processor)
        {
            Processor = processor;
        }

        protected IProcessor Processor { get; set; }

        #region IAdapter Members

        public virtual ServiceRequest ReadRequest()
        {
            var request = HttpContext.Current.Request;
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
                LOG.Debug("Analizing request...");
                LOG.Debug(string.Format("RequestType : {0}", request.RequestType));
                LOG.Debug(string.Format("UserAgent : {0}", request.UserAgent));
                LOG.Debug(string.Format("UserHostAddress : {0}", request.UserHostAddress));
                LOG.Debug(string.Format("UserHostName : {0}", request.UserHostName));
                LOG.Debug(string.Format("ContentType : {0}", request.ContentType));
                LOG.Debug(string.Format("HttpMethod : {0}", request.HttpMethod));

                if (request.QueryString != null && request.QueryString.Count > 0)
                {
                    LOG.Debug(string.Format("The query string: {0}", request.QueryString));
                    foreach (var key in request.QueryString.Keys)
                    {
                        LOG.Debug(string.Format("[QueryString] Key: {0}, Value: {1}", key,
                                                request.QueryString[(string) key]));
                    }
                }
                if (request.Headers != null && request.Headers.Count > 0)
                {
                    LOG.Debug(string.Format("Headers collection: {0}", request.Headers));
                    foreach (var key in request.Headers.Keys)
                    {
                        LOG.Debug(string.Format("[Header] Key: {0}, Value: {1}", key, request.Headers[(string) key]));
                    }
                }
                if (request.Form != null && request.Form.Count > 0)
                {
                    LOG.Debug(string.Format("Form values: {0}", request.Form));
                    foreach (var key in request.Form.Keys)
                    {
                        LOG.Debug(string.Format("[FormValue] Key: {0}, Value: {1}", key, request.Form[(string) key]));
                    }
                }
                if (request.Files != null && request.Files.Count > 0)
                {
                    LOG.Debug(string.Format("The Files collection: {0}", request.Files));
                    foreach (var key in request.Files.Keys)
                    {
                        var file = request.Files[(string) key];
                        LOG.Debug(
                            string.Format("[PostedFile] Key: {0}, FileName: {1}, ContentType: {2}, ContentLength: {3}",
                                          key, file.FileName, file.ContentType, file.ContentLength));
                    }
                }
                LOG.Debug("Analisys finished.");
                LOG.Debug("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            }
            var reader = new StreamReader(request.InputStream);
            var requestStr = reader.ReadToEnd();
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug(string.Format("Request string readed: {0}", requestStr));
            }
            return Processor.Decode(requestStr);
        }

        public virtual void WriteResponse(ServiceRequest request, ServiceResponse response)
        {
            var encodedResponse = Processor.Encode(request, response);
            HttpContext.Current.Response.Write(encodedResponse);
        }

        public virtual void WriteResponse(ServiceResponse response)
        {
            var encodedResponse = Processor.Encode(response);
            HttpContext.Current.Response.Write(encodedResponse);
        }

        #endregion
    }
}